﻿#!/usr/bin/env python
# -*- coding: utf-8 -*-

import os, sys, time
from PyQt4 import QtGui, QtCore
import QonsoFactory
from QonsoModel import QonsoModel
from DlgConfig import DlgConfig
from WProgress import WProgress
from DebugLog import DebugLog

class QonsoView(QtGui.QMainWindow):
   def __init__(self, argv, parent=None):
      QtGui.QMainWindow.__init__(self, parent)

      DebugLog("QonsoView::Init")
      self.offline = os.environ.has_key('OFFLINE')
      self.setMaximumSize(QtCore.QSize(800, 480))
      self.setMinimumSize(QtCore.QSize(480, 480))
      self.setWindowTitle('Qonso')

      self.vbox = None
      self.boxes = dict(
                  voix=None,
                  voixSupp = None,
                  sms = None,
                  smsSupp = None,
                  data = None,
                  hforfait = None,
                  facture = None)

      try:
         self.setAttribute(QtCore.Qt.WA_Maemo5AutoOrientation, True)
      except AttributeError:
         # not on Maemo5
         pass

      self.labels = dict()
      self.config = DlgConfig()
      self.model = QonsoModel()
      self.extractor = None
      self.credentialsOk = False

      if not self.config.GetLogin() or not self.config.GetPassword() or not self.config.GetOperator():
         self.config.AskForCredentials()

      self.layoutsOK = False
      self.centralWidget = QtGui.QWidget()

      self.vbox = QtGui.QVBoxLayout()
      self.centralWidget.setLayout(self.vbox)
      self.setCentralWidget( self.centralWidget )
      self.firstDisplay = True

      self.credentialsOk = True
      self.CreateAppLayouts()

   def DataInit(self):
      DebugLog("QonsoView::DataInit")
      if self.offline:
         self.CreateExtractor(sys.argv[1])
         f = open( sys.argv[2], "r")
         self.extractor.SetOffline(True)
         self.extractor.ExtractDatas( f.read() )
         f.close()
         self.CreateConsoLayouts()
         self.extractor.authentication = 'Done'
      else:
         self.CreateExtractor( self.config.GetOperator() )
         self.extractor.SetOffline(False)
         self.extractor.InitAuthenticate()

   def CreateExtractor(self, op):
      DebugLog("QonsoView::CreateExtractor")
      self.extractor = QonsoFactory.CreateExtractor(op)
      self.extractor.SetView(self)
      self.extractor.SetLogin(self.config.GetLogin())
      self.extractor.SetPassword(self.config.GetPassword())
      self.extractor.SetModel(self.model)
      self.connect(self.extractor, QtCore.SIGNAL("progress"), self.UpdateBar)
      self.connect(self.extractor, QtCore.SIGNAL('extracted'), self.UpdateConsoText, QtCore.Qt.QueuedConnection)

   def UpdateBar(self):
      DebugLog("QonsoView::UpdateBar(%f)"%self.extractor.GetProgress())
      self.statusLabel[1].setValue( self.extractor.GetProgress() )

   def Settings(self):
      self.config.AskForCredentials()
      if self.config.updated:
         self.Reset()
         self.update()
         self.credentialsOk = True
         self.layoutsOK = False
         self.extractor = None

   def Reset(self):
      DebugLog("QonsoView::Reset")
      self.model = QonsoModel()
      self.vbox.removeItem(self.statusBox)

      for label in self.labels:
         data, wid = self.labels[label]
         if not self.boxes.has_key(label):
            del data
            del wid

         else:
            if data:
               DebugLog("removing data "+label)
               self.boxes[label].removeWidget(data)
               del data

            if wid:
               DebugLog("removing wid "+label)
               self.boxes[label].removeWidget(wid)
               del wid

            self.vbox.removeItem(self.boxes[label])
            del self.boxes[label]

      self.labels.clear()
      self.boxes.clear()
      self.statusLabel[0].show()
      self.statusLabel[1].show()

   def CreateAppLayouts(self):
      DebugLog("QonsoView::CreateAppLayouts")
      exit = QtGui.QAction(u'Paramètres', self)
      exit.setShortcut('Ctrl+O')
      self.connect(exit, QtCore.SIGNAL('triggered()'),self.Settings)

      update = QtGui.QAction(u'Rafraichir', self)
      update.setShortcut('Ctrl+R')
      self.connect(update, QtCore.SIGNAL('triggered()'), self.UpdateConso)

      about = QtGui.QAction(u'A propos...', self)
      self.connect(about, QtCore.SIGNAL('triggered()'), self.About)

      menubar = self.menuBar()
      file = menubar.addMenu('&Options')
      file.addAction(exit)
      file.addAction(update)
      file.addAction(about)

      self.statusBox, label, progress = self.CreateLayout('status', None, True)
      self.statusLabel = label, progress
      self.statusLabel[1].setShowRules(False)

      self.vbox.addLayout(self.statusBox)
      self.vbox.setSpacing(0)
      self.vbox.setMargin(0)

   def CreateConsoLayouts(self):
      DebugLog("QonsoView::CreateConsoLayouts")

      iconPath = '/opt/qonso/icons'
      if not os.path.exists(iconPath):
         iconPath = 'icons'

      self.CreateAndAddLayout('compte', None)
      self.CreateAndAddLayout('voix', os.path.join(iconPath, 'voix.png'), self.model.GetConsoVoixMax('int')!=None )

      if self.model.GetConsoVoixSupp('str'):
         self.CreateAndAddLayout('voixSupp', os.path.join(iconPath, 'voixsupp.png'), True)

      if self.model.GetConsoSMSMax() != '0':
         self.CreateAndAddLayout('sms', os.path.join(iconPath, 'sms.png') )

      if self.model.GetConsoSMSSupp():
         self.CreateAndAddLayout('smsSupp', os.path.join(iconPath, 'smssupp.png') )

      if self.model.GetConsoDataMax('int')>0:
         self.CreateAndAddLayout('data', os.path.join(iconPath, 'data.png'), True)

      if self.model.GetConsoHorsForfait()!=None:
         self.CreateAndAddLayout('hforfait', os.path.join(iconPath, 'hforfait.png'), False)

      if self.model.GetDateProchaineFacture()!=None:
         self.CreateAndAddLayout('facture', None)

      self.layoutsOK = True
      self.UpdateConsoText()

   def CreateAndAddLayout(self, name, icon, progress=False):
      DebugLog("QonsoView::CreateAndAddLayout "+name)
      box, label, progress = self.CreateLayout(name, icon, progress)
      self.boxes[name] = box
      self.labels[name] = label, progress
      self.vbox.addLayout(self.boxes[name])

   def CreateLayout(self, name, icon, progress=False):
      DebugLog("QonsoView::CreateLayout(%s, %s, %d)" % (name, str(icon), progress) )

      box = QtGui.QHBoxLayout()
      box.setSpacing(0)
      box.setMargin(0)

      if icon:
         pixicon = QtGui.QPixmap(icon).scaled(64,64)
         label = QtGui.QLabel()
         label.setMinimumSize(QtCore.QSize(74, 74))
         label.setMaximumSize(QtCore.QSize(96, 250))
         label.setStyleSheet("background: #fff; margin: 0; padding: 5px; border-bottom: 1px solid #269CCA;")
         label.setPixmap(pixicon)
         box.addWidget(label)

      data = QtGui.QLabel()

      sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Preferred, QtGui.QSizePolicy.Preferred)
      sizePolicy.setHorizontalStretch(1)
      sizePolicy.setVerticalStretch(1)
      sizePolicy.setHeightForWidth(data.sizePolicy().hasHeightForWidth())
      data.setSizePolicy(sizePolicy)
      data.setMaximumSize(QtCore.QSize(800, 800))
      data.setStyleSheet("background: #fff;")
      data.setAlignment(QtCore.Qt.AlignCenter)

      vbox = QtGui.QVBoxLayout()
      vbox.addWidget(data)
      wid = None

      if progress:
#         wid = QtGui.QProgressBar()
         wid = WProgress(self)
         wid.setStyleSheet("background: #fff; margin: 0; padding: 10px; border-bottom: 1px solid #269CCA")
         vbox.addWidget(wid)
         wid.setMaximumSize(QtCore.QSize(800, 70))
      else:
         data.setStyleSheet("background: #fff; margin: 0; padding: 5px; border-bottom: 1px solid #269CCA")

      box.addLayout(vbox)

      return box, data, wid

   def UpdateConsoText(self):
      if not self.extractor:
         return

      status, context = self.extractor.GetStatus()

      if status=='ERROR':
         self.SetText(self.statusLabel[0], "#F00", 16, context)
         self.statusLabel[1].setValue( self.extractor.GetProgress() )

      elif status=='DONE':
         self.statusLabel[0].hide()
         self.statusLabel[1].hide()

      else:
         self.SetText(self.statusLabel[0], "#269CCA", 16, context)
         # self.statusLabel[1].setValue( self.extractor.GetProgress() )
         #time.sleep(1)
         #self.update()

      if self.labels.has_key('compte') and self.model.GetLastTime():
         self.SetText(self.labels['compte'][0], "#269CCA", 16, self.model.GetLastTime()+
                      "<br/>"+self.model.GetReport('str'))

      if self.labels.has_key('voix'):
         s = self.model.GetConsoVoix('str')
         if self.model.GetConsoVoixMax('str'):
            s += " / "+self.model.GetConsoVoixMax('str')
            self.labels['voix'][1].setRange(0, self.model.GetConsoVoixMax('int'))
            self.labels['voix'][1].setValue( self.model.GetConsoVoix('int') )
         self.SetText(self.labels['voix'][0], "#EB5F18", 20, s)

      if self.labels.has_key('voixSupp'):
         self.SetText(self.labels['voixSupp'][0], "#EB5F18", 20, self.model.GetConsoVoixSupp('str')+" / "+self.model.GetConsoVoixSuppMax('str') )
         self.labels['voixSupp'][1].setRange(0, self.model.GetConsoVoixSuppMax('int'))
         self.labels['voixSupp'][1].setValue( self.model.GetConsoVoixSupp('int') )

      if self.labels.has_key('sms'): # and self.model.GetConsoSMSMax() != '0':
         self.SetText(self.labels['sms'][0], "#EB5F18", 20, self.model.GetConsoSMS() +"/" + self.model.GetConsoSMSMax())

      if self.labels.has_key('smsSupp'):
         self.SetText(self.labels['smsSupp'][0], "#EB5F18", 20, self.model.GetConsoSMSSupp() +"/" + self.model.GetConsoSMSSuppMax())

      if self.labels.has_key('data'):
         dataMax = self.model.GetConsoDataMax('int')
         dataMaxstr = self.model.GetConsoDataMax('str')
         data = self.model.GetConsoData('int')
         datastr = self.model.GetConsoData('str')
         self.SetText(self.labels['data'][0], "#EB5F18", 20, "%s/%sMo"%(datastr, dataMaxstr))
         self.labels['data'][1].setRange(0, dataMax)
         self.labels['data'][1].setValue( data )

      if self.labels.has_key('hforfait'):
         self.SetText(self.labels['hforfait'][0], "#EB5F18", 20, self.model.GetConsoHorsForfait() )

      if self.labels.has_key('facture'):
         self.SetText(self.labels['facture'][0], "#269CCA", 16, self.model.GetDateProchaineFacture())

      self.update()

   def SetText(self, label, color, size, text):
      label.setText('<span style="color: %s; font-weight: bold; font-size: %dpt">%s</span>' % (color, size, text))

   def UpdateConso(self):
      DebugLog("QonsoView::UpdateConso")
      self.extractor.UpdateConso()

   def About(self):
      QtGui.QMessageBox.about(self, "A propos", u'Qonso\nDéveloppé par Gérald Fauvelle\nhttp://projects.forum.nokia.com/Qonso')
      return

   def paintEvent(self, event):
      if self.firstDisplay:
         if self.credentialsOk and (not self.extractor or not self.extractor.authentication):
            self.DataInit()
         elif not self.layoutsOK:
            if self.extractor and self.extractor.datasExtracted:
               self.CreateConsoLayouts()
               self.extractor.datasExtracted = False
      self.firstDisplay = True
      self.UpdateConsoText()
      event.accept()

   def closeEvent(self, event):
      self.config.WriteConfig()
      event.accept()
